from datetime import datetime
from functools import wraps
from flask import Blueprint, jsonify, redirect, render_template, request, session, url_for
from app.models import db
from app.patient.models import Patient
from app.models import *
from app.patient.utils import patient_required, patient_required_web
from app.utils import hash_password, process_request_data

patient = Blueprint('patient', __name__, template_folder='templates')


@patient.route('/register_patient', methods=['POST'])
def register_patient():
    data = process_request_data(request)
    username = data.get('username')
    password = hash_password(data.get('password'))
    if username is None or password is None:
        return jsonify({"code": 1, 'message': 'Invalid request'})
    if Patient.query.filter_by(username=username).first() is not None:
        return jsonify({"code": 1, 'message': 'Username already exists'})
    try:
        new_patient = Patient(**data)
    except:
        return jsonify({"code": 1, 'message': 'Invalid request'}), 400
    db.session.add(new_patient)
    db.session.commit()
    return jsonify({"code": 0, 'message': 'Patient registered successfully'})

# Additional routes for modify patient info, appointment booking, etc.


@patient.route('/login_patient', methods=['POST'])
def login_patient():
    data = process_request_data(request)
    username = data.get('username')
    password = data.get('password')
    if username is None or password is None:
        return jsonify({"code": 1, 'message': 'Invalid request'})
    patient = Patient.query.filter_by(username=username).first()
    if patient is None:
        return jsonify({"code": 1, 'message': 'Invalid username or password'})
    if not patient.check_password(password):
        return jsonify({"code": 1, 'message': 'Invalid username or password'})

    session['username'] = username
    session['patient_id'] = patient.id
    return jsonify({"code": 0, 'message': 'Login successful'})


@patient.route('/logout_patient', methods=['POST'])
@patient_required
def logout_patient():
    session.pop('username', None)
    session.pop('patient_id', None)
    return jsonify({"code": 0, 'message': 'Logout successful'})


@patient.route('/modify_patient_info', methods=['POST'])
@patient_required
def modify_patient_info():
    data = process_request_data(request)
    patient_id = session.get('patient_id')

    if not patient_id:
        return jsonify({"code": 2, 'message': 'Patient ID not found in session'})

    if not data:
        return jsonify({"code": 3, 'message': 'No data provided to update'})

    # 假设 'id' 字段不应该在请求数据中，因为它由 session 提供
    if "id" in data:
        data.pop('id')

    try:
        # 查找患者记录
        patient = Patient.query.get(patient_id)
        if not patient:
            return jsonify({"code": 4, 'message': 'Patient not found'})

        # 更新患者信息
        for key, value in data.items():
            # 假设所有字段都存在于Patient模型中，并且可以直接赋值
            setattr(patient, key, value)

        # 提交数据库会话
        db.session.commit()

    except Exception as e:
        # 捕获所有异常，但通常最好捕获特定的异常类型
        db.session.rollback()  # 如果出现错误，回滚数据库会话
        return jsonify({"code": 1, 'message': 'Invalid request: ' + str(e)})

    return jsonify({"code": 0, 'message': 'Patient info updated successfully'})


@patient.route('/get_patient_profile', methods=['GET'])
@patient_required
def get_patient_profile():
    patient = Patient.query.get(session['patient_id'])
    if patient is None:
        return jsonify({"code": 1, 'message': 'Invalid patient ID'})

    return jsonify({"code": 0, "data": patient.to_dict()})


@patient.route('/get_patient_appointments', methods=['GET'])
@patient_required
def get_patient_appointments():
    appointments = Appointment.query.filter_by(
        patient_id=session.get('patient_id')).all()
    return jsonify({"code": 0, "data": [appointment.to_dict() for appointment in appointments]})


@patient.route('/book_appointments', methods=['POST'])
@patient_required
def book_appointments():
    data = process_request_data(request)
    package_id = data.get('package_id')
    appointment_time = data.get('appointment_time')
    if package_id is None or appointment_time is None:
        return jsonify({"code": 1, 'message': 'Invalid request'})

    package = Package.query.get(package_id)
    if package is None:
        return jsonify({"code": 1, 'message': 'Invalid package ID'})

    new_appointment = Appointment(
        patient_id=session['patient_id'],
        package_id=package_id,
        appointment_time=datetime.strptime(appointment_time, '%Y-%m-%d %H:%M'),
        status='pending'
    )
    db.session.add(new_appointment)
    db.session.commit()
    return jsonify({"code": 0, 'message': 'Appointment booked successfully'})


@patient.route('/cancel_appointment', methods=['POST'])
@patient_required
def cancel_appointment():
    data = process_request_data(request)

    appointment = Appointment.query.filter_by(**data).first()
    if appointment is None:
        return jsonify({"code": 1, 'message': 'Invalid appointment ID'})

    if appointment.patient_id != session['patient_id']:
        return jsonify({"code": 1, 'message': 'Not authorized'})
    if appointment.status != 'pending':
        return jsonify({"code": 1, 'message': 'Appointment cannot be cancelled'})
    appointment.status = 'cancelled'
    db.session.commit()
    return jsonify({"code": 0, 'message': 'Appointment cancelled successfully'})


@patient.route('/get_appointment_details', methods=['POST'])
@patient_required
def get_appointment_details():

    data = process_request_data(request)
    appointment = Appointment.query.filter_by(**data).first()
    if appointment is None:
        return jsonify({"code": 1, 'message': 'Invalid appointment ID'})

    if appointment.patient_id != session['patient_id']:
        return jsonify({"code": 1, 'message': 'Not authorized'})

    return jsonify({"code": 0, "data": appointment.to_dict()})


# 用于跳转的根路由
@patient.route('/')
@patient_required_web
def root_patient():
    return redirect(url_for('patient.dashboard_patient_web'))


# 用户面板
# 包含跳转按钮 -> /appointment_web
@patient.route('/dashboard_patient_appointments_list_web')
@patient_required_web
def dashboard_patient_appointments_list_web():
    return render_template('patient/dashboard_patient_appointments_list_web.html')


@patient.route('/dashboard_patient_web')
@patient_required_web
def dashboard_patient_web():
    return render_template('patient/dashboard_patient_web.html')


# 用于跳转的退出登陆路由
@patient.route('/logout_patient_web')
@patient_required_web
def logout_patient_web():
    session.pop('username', None)
    session.pop('patient_id', None)
    return redirect(url_for('patient.root_patient'))

# 注册界面


@patient.route('/register_patient_web')
def register_patient_web():
    return render_template('patient/register_patient_web.html')


# 登陆界面
@patient.route('/login_patient_web')
def login_patient_web():
    return render_template('patient/login_patient_web.html')


# 预约界面
# 请求使用jquery ajax
# 信息显示在开头的<div id="message"></div>里
# 要能从{{url_for('doctor.query_package')}} (POST {})获得体检套餐列表

# 要能从{{url_for('doctor.query_item')}} (POST {})获得体检项目列表

# 拼接两者而成可选体检列表
# 预约时间选择

@patient.route('/appointment_patient_web')
@patient_required_web
def appointment_patient_web():
    return render_template('patient/appointment_patient_web.html')
